home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 4 / The Arsenal Files 4 (Arsenal Computer).ISO / ham / sattrk31.tgz / sattrack-3.1.tar / SatTrack / src / sattrack / satelem.c < prev    next >
Text File  |  1995-03-16  |  19KB  |  431 lines

  1. /******************************************************************************/
  2. /*                                                                            */
  3. /*  Title       : satelem.c                                                   */
  4. /*  Author      : Manfred Bester                                              */
  5. /*  Date        : 19Jun91                                                     */
  6. /*  Last change : 15Mar95                                                     */
  7. /*                                                                            */
  8. /*  Synopsis    : This function reads the NORAD/NASA 2-line element sets.     */
  9. /*                                                                            */
  10. /*                                                                            */
  11. /*  Data for each satellite consist of three lines in the following format:   */
  12. /*                                                                            */
  13. /*  XXXXXXXXXXX                                                               */
  14. /*  1 AAAAAU 00  0  0 BBBBB.BBBBBBBB +.CCCCCCCC +DDDDD-D +EEEEE-E F  GGGZ     */
  15. /*  2 AAAAA HHH.HHHH III.IIII JJJJJJJ KKK.KKKK LLL.LLLL MM.MMMMMMMMNNNNNZ     */
  16. /*                                                                            */
  17. /*  X = Satellite name                                                        */
  18. /*  A = Catalog number                                                        */
  19. /*  B = Epoch time                                                            */
  20. /*  C = One half of first derivative of mean motion (decay rate)              */
  21. /*  D = One sixth of second derivative of mean motion                         */
  22. /*  E = BSTAR drag coefficient                                                */
  23. /*  F = Ephemeris type                                                        */
  24. /*  G = Number of the element set                                             */
  25. /*  H = Inclination                                                           */
  26. /*  I = RAAN                                                                  */
  27. /*  J = Eccentricity                                                          */
  28. /*  K = Argument of perigee                                                   */
  29. /*  L = Mean anomaly                                                          */
  30. /*  M = Mean motion                                                           */
  31. /*  N = Orbit number                                                          */
  32. /*  Z = Check sum (modulo 10)                                                 */
  33. /*                                                                            */
  34. /*                                                                            */
  35. /*  Line 0 is an eleven-character name. Lines 1 and 2 are the standard        */
  36. /*  two-line orbital element set format identical to that used by NASA and    */
  37. /*  NORAD. The format description is as follows:                              */
  38. /*                                                                            */
  39. /*  Line 0:                                                                   */
  40. /*  Column     Description                                                    */
  41. /*    1-11     Satellite name                                                 */
  42. /*                                                                            */
  43. /*  Line 1:                                                                   */
  44. /*    1- 1     Line number of element set                                     */
  45. /*    3- 7     Satellite number                                               */
  46. /*    8- 8     Classification (U = unclassified)                              */
  47. /*   10-11     International designator (last two digits of launch year)      */
  48. /*   12-14     International designator (launch number of the year)           */
  49. /*   15-17     International designator (piece of launch)                     */
  50. /*   19-20     Epoch year (last two digits of year)                           */
  51. /*   21-32     Epoch (Julian day and fractional portion of the day)           */
  52. /*   34-43     One half of first time derivative of mean motion (decay rate)  */
  53. /*             or ballistic coefficient (depending on ephemeris type)         */
  54. /*   45-52     One sixth of second time derivative of mean motion             */
  55. /*             (decimal point assumed; blank if n/a)                          */
  56. /*   54-61     BSTAR drag coefficient if SGP4/SGP8 general perturbation       */
  57. /*             theory used; otherwise, radiation pressure coefficient         */
  58. /*             (decimal point assumed)                                        */
  59. /*   63-63     Ephemeris type                                                 */
  60. /*   66-68     Element set number                                             */
  61. /*   69-69     Check sum (modulo 10)                                          */
  62. /*             (letters, blanks, periods, plus sign = 0; minus sign = 1)      */
  63. /*                                                                            */
  64. /*  Line 2:                                                                   */
  65. /*    1- 1     Line number of element set                                     */
  66. /*    3- 7     Satellite number                                               */
  67. /*    9-16     Inclination [deg]                                              */
  68. /*   18-25     Right Ascension of the ascending node [deg]                    */
  69. /*   27-33     Eccentricity (decimal point assumed)                           */
  70. /*   35-42     Argument of perigee [deg]                                      */
  71. /*   44-51     Mean anomaly [deg]                                             */
  72. /*   53-63     Mean motion [rev/d]                                            */
  73. /*   64-68     Orbit (revolution number) at epoch [rev]                       */
  74. /*   69-69     Check sum (modulo 10)                                          */
  75. /*                                                                            */
  76. /*  All other columns are blank or fixed.                                     */
  77. /*                                                                            */
  78. /*                                                                            */
  79. /*  SatTrack is Copyright (c) 1992, 1993, 1994, 1995 by Manfred Bester.       */
  80. /*  All Rights Reserved.                                                      */
  81. /*                                                                            */
  82. /*  Permission to use, copy, and distribute SatTrack and its documentation    */
  83. /*  in its entirety for educational, research and non-profit purposes,        */
  84. /*  without fee, and without a written agreement is hereby granted, provided  */
  85. /*  that the above copyright notice and the following three paragraphs appear */
  86. /*  in all copies. SatTrack may be modified for personal purposes, but        */
  87. /*  modified versions may NOT be distributed without prior consent of the     */
  88. /*  author.                                                                   */
  89. /*                                                                            */
  90. /*  Permission to incorporate this software into commercial products may be   */
  91. /*  obtained from the author, Dr. Manfred Bester, 1636 M. L. King Jr. Way,    */
  92. /*  Berkeley, CA 94709, USA. Note that distributing SatTrack 'bundled' in     */
  93. /*  with ANY product is considered to be a 'commercial purpose'.              */
  94. /*                                                                            */
  95. /*  IN NO EVENT SHALL THE AUTHOR BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, */
  96. /*  SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OF   */
  97. /*  THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE AUTHOR HAS BEEN ADVISED  */
  98. /*  OF THE POSSIBILITY OF SUCH DAMAGE.                                        */
  99. /*                                                                            */
  100. /*  THE AUTHOR SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT      */
  101. /*  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A   */
  102. /*  PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN "AS IS"      */
  103. /*  BASIS, AND THE AUTHOR HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, */
  104. /*  UPDATES, ENHANCEMENTS, OR MODIFICATIONS.                                  */
  105. /*                                                                            */
  106. /******************************************************************************/
  107.  
  108. #include <math.h>
  109. #include <stdio.h>
  110. #include <string.h>
  111.  
  112. #ifndef STDLIB
  113. #include <stdlib.h>
  114. #endif
  115.  
  116. #include "satglobalsx.h"
  117. #include "sattrack.h"
  118.  
  119. #ifdef HPTERM
  120. #include "hpterm.h"               /* definitions of hpterm macros             */
  121. #else
  122. #include "vt100.h"                /* definitions of VT100 macros              */
  123. #endif
  124.  
  125. /******************************************************************************/
  126. /*                                                                            */
  127. /* readTleFile: reads entire data file with two-line Keplerian elements into  */
  128. /*              a structure                                                   */
  129. /*                                                                            */
  130. /* return code: 0 = no error                                                  */
  131. /*              1 = file not found                                            */
  132. /*                                                                            */
  133. /******************************************************************************/
  134.  
  135. int readTleFile(homeDir,elementFile,nTle)
  136.  
  137. int  nTle;
  138. char *homeDir, *elementFile;
  139.  
  140. {
  141.     int  k, duplFlag;
  142.     char str[80], line0[80], line1[80], line2[80], inputFile[120];
  143.     FILE *fpi;
  144.  
  145.     lowerCase(elementFile);
  146.     sprintf(inputFile,"%s/%s/%s",homeDir,TLE,elementFile);
  147.  
  148.     if ((fpi = fopen(inputFile, "r")) == NULL)
  149.         return(1);
  150.  
  151.     if (verboseFlag)
  152.         printf("\nreading TLE data from %s ...\n",elementFile);
  153.  
  154.     while (fgets(str,80,fpi) && nTle < MAXSATS)
  155.     {
  156.         sprintf(line0,"%s",str);
  157.         line0[(int) strlen(line0) - 1] = '\0';
  158.         truncBlanks(line0);
  159.         cleanSatName(line0);
  160.  
  161.         fgets(str,80,fpi);
  162.         sprintf(line1,"%s",str);
  163.         line1[(int) strlen(line1) - 1] = '\0';
  164.         truncBlanks(line1);
  165.  
  166.         fgets(str,80,fpi);
  167.         sprintf(line2,"%s",str);
  168.         line2[(int) strlen(line2) - 1] = '\0';
  169.         truncBlanks(line2);
  170.  
  171.         satNum   = (long) (getElement(line1,3,7) + ONEPPM);
  172.         duplFlag = FALSE;
  173.  
  174.         for (k = 0; k < nTle; k++)             /* check for duplicate entries */
  175.         {                                      /* using the object number     */
  176.             if (satNum == tle[k].tleSatNum)
  177.                 duplFlag = TRUE;
  178.         }
  179.  
  180.         if (!duplFlag)                         /* add TLE set to structure    */
  181.         {
  182.             strcpy(tle[nTle].tleLine0,line0);
  183.             strcpy(tle[nTle].tleLine1,line1);
  184.             strcpy(tle[nTle].tleLine2,line2);
  185.        
  186.             tle[nTle].tleSatNum = satNum;
  187.             nTle++;
  188.         }
  189.     }
  190.  
  191.     fclose(fpi);
  192.     numTle = nTle;
  193.  
  194.     if (verboseFlag)
  195.         printf("data base contains %d element sets\n",numTle);
  196.  
  197.     return(0);
  198. }
  199.  
  200. /******************************************************************************/
  201. /*                                                                            */
  202. /* getTleSets: reads all tle sets from tlex.dat                               */
  203. /*                                                                            */
  204. /******************************************************************************/
  205.  
  206. void getTleSets()
  207.  
  208. {
  209.     int error;
  210.  
  211.     error = readTleFile(strpHome,TLEX,0);
  212.  
  213.     if (error)
  214.     {
  215.         doBeep(); nl(); reverseBlink();
  216.         printf(" File '%s' not found \n",TLEX);
  217.         normal(); nl();
  218.         exit(-1);
  219.     }
  220.  
  221.     return;
  222. }
  223.  
  224. /******************************************************************************/
  225. /*                                                                            */
  226. /* readTle: reads two-line element set for a specified satellite              */
  227. /*                                                                            */
  228. /* return code: 0 = data valid                                                */
  229. /*              1 = check sum error in line 1                                 */
  230. /*              2 = check sum error in line 2                                 */
  231. /*              3 = specified satellite not found                             */
  232. /*              4 = multiple entries for specified satellite                  */
  233. /*                                                                            */
  234. /* satNameFlag:   TRUE allows fraction of satellite name                      */
  235. /*                FALSE only allows exact satellite name                      */
  236. /*                if object number is specified, this flag is without effect  */
  237. /*                                                                            */
  238. /******************************************************************************/
  239.  
  240. int readTle(satNameFlag,satNameTle,pSatNum,pElementSet,
  241.             pEpochDay,pInclination,pRaan,pEccentricity,
  242.             pArgPerigee,pMeanAnomaly,pMeanMotion,
  243.             pDecayRate,pDecayRateDot,pbStarCoeff,
  244.             pOrbitNum,pEphemerisType)
  245.  
  246. double *pEpochDay, *pInclination, *pRaan, *pEccentricity, *pArgPerigee;
  247. double *pMeanAnomaly, *pMeanMotion, *pDecayRate, *pDecayRateDot, *pbStarCoeff;
  248. long   *pSatNum, *pOrbitNum;
  249. int    satNameFlag, *pElementSet, *pEphemerisType;
  250. char   *satNameTle;
  251.  
  252. {
  253.     double epochYear, exponent, atofSatNum, checkLow, checkHigh;
  254.     long   strSatNum;
  255.     long   tleSatNum  = 0L;
  256.     long   saveSatNum = 0L;
  257.     int    error, satNameLen, checkSum, checkValue, takeSatNum;
  258.     int    i, j, m, n;
  259.     int    tleIndex = 0;
  260.     char   line0[80], line1[80], line2[80], str[80], strng[10], saveStr[80];
  261.     char   tleStr[80];
  262.  
  263.     satNameLen = strlen(satNameTle);
  264.     atofSatNum = atof(satNameTle);
  265.  
  266.     checkLow   = pow(10.0,(double) (satNameLen - 1)) - ONEPPM;
  267.     checkHigh  = pow(10.0,(double) (satNameLen)) - 1.0 + ONEPPM;
  268.  
  269.     takeSatNum = (atofSatNum > checkLow && 
  270.                   atofSatNum < checkHigh) ? TRUE : FALSE;
  271.  
  272.     if (takeSatNum)
  273.         satNameFlag = FALSE;
  274.  
  275.     upperCase(satNameTle);
  276.  
  277.     error = FALSE;
  278.     m     = 0;
  279.  
  280.     for (i = 0; i < numTle; i++)               /* check for ambiguous entries */
  281.     {
  282.         if (m == 1)
  283.         {
  284.             strcpy(saveStr,tleStr);
  285.             saveSatNum = tleSatNum;
  286.         }
  287.  
  288.         strcpy(str,tle[i].tleLine0);
  289.         upperCase(str);
  290.         strSatNum = tle[i].tleSatNum;
  291.  
  292.         n = (satNameFlag) ? satNameLen : strlen(str);
  293.  
  294.         if ((!takeSatNum && n == satNameLen && 
  295.              !strncmp(satNameTle,str, (unsigned int) satNameLen)) || 
  296.             (takeSatNum && (long) (atofSatNum + ONEPPM) == strSatNum))
  297.         {
  298.             strcpy(tleStr,tle[i].tleLine0);
  299.             tleSatNum = tle[i].tleSatNum;
  300.  
  301.             if (m == 0)
  302.                 tleIndex = i;
  303.  
  304.             if (m == 1)
  305.                 printf("\n%5ld:  %s\n",saveSatNum,saveStr);
  306.  
  307.             if (m >= 1)
  308.                 printf("%5ld:  %s\n",tleSatNum,tleStr);
  309.  
  310.             m++;
  311.         }
  312.     }
  313.  
  314.     if (m == 0)                                        /* satellite not found */
  315.         return(3);
  316.  
  317.     if (m > 1)                                         /* multiple entries    */
  318.         return(4);
  319.  
  320.     strcpy(line0,tle[tleIndex].tleLine0);              /* continue if m = 1   */
  321.     truncBlanks(line0);                                /* (only one entry)    */
  322.  
  323.     strcpy(satNameTle,line0);
  324.     strcpy(line1,tle[tleIndex].tleLine1);                      /* read line 1 */
  325.     strcpy(line2,tle[tleIndex].tleLine2);                      /* read line 2 */
  326.  
  327.     if (verboseFlag)
  328.     {
  329.         nl();
  330.         printf("%s\n",line0);
  331.         printf("%s\n",line1);
  332.         printf("%s\n",line2);
  333.         nl();
  334.     }
  335.  
  336.     for (j = 2; j <= 3; j++)             /* perform CRC test on lines 1 and 2 */
  337.     {
  338.         if (j == 2) sprintf(str,"%s",line1);                /* j = error code */
  339.         if (j == 3) sprintf(str,"%s",line2);
  340.  
  341.         checkSum = 0;
  342.  
  343.         for (i = 0; i < 68; i++)
  344.         {
  345.             strng[0]   = str[i];
  346.             strng[1]   = '\0';
  347.             checkValue = atoi(strng);
  348.  
  349.             if (!strcmp(strng,"-"))
  350.                 checkValue = 1;              /* assign check sum value to '-' */
  351.  
  352.             checkSum += checkValue;
  353.         }
  354.  
  355.         strng[0] = str[68];
  356.         strng[1] = '\0';
  357.  
  358.         if (atoi(strng) != checkSum % 10)
  359.         {
  360.             error = j - 1;
  361.  
  362.             if (verboseFlag)
  363.             {
  364.                 doBeep(); nl(); reverseBlink();
  365.                 printf(" Check sum error in TLE set, line %d: ",error);
  366.                 printf("check sum is %d, should be %d \n",
  367.                     checkSum%10,atoi(strng));
  368.                 normal();
  369.             }
  370.  
  371.             return(error);
  372.         }
  373.     }
  374.  
  375.     *pSatNum        = (long) (getElement(line1, 3, 7) + ONEPPM);
  376.     *pOrbitNum      = (long) (getElement(line2,64,68) + ONEPPM);
  377.     *pEphemerisType = (int)  (getElement(line1,63,63) + ONEPPM);
  378.     *pElementSet    = (int)  (getElement(line1,66,68) + ONEPPM);
  379.  
  380.     epochYear       = getElement(line1,19,20);
  381.     *pEpochDay      = getElement(line1,21,32) + epochYear * 1000.0;
  382.     *pInclination   = getElement(line2, 9,16);
  383.     *pRaan          = getElement(line2,18,25);
  384.     *pEccentricity  = getElement(line2,27,33) * 1.0e-7;
  385.     *pArgPerigee    = getElement(line2,35,42);
  386.     *pMeanAnomaly   = getElement(line2,44,51);
  387.     *pMeanMotion    = getElement(line2,53,63);
  388.     *pDecayRate     = getElement(line1,34,43);
  389.  
  390.     exponent        = getElement(line1,51,52);
  391.     *pDecayRateDot  = getElement(line1,45,50) * pow(10.0,-5.0 + exponent);
  392.  
  393.     exponent        = getElement(line1,60,61);
  394.     *pbStarCoeff    = getElement(line1,54,59) * pow(10.0,-5.0 + exponent);
  395.  
  396.     return(0);
  397. }
  398.  
  399. /******************************************************************************/
  400. /*                                                                            */
  401. /* getElement: returns double of orbital element out of ASCII string          */
  402. /*                                                                            */
  403. /******************************************************************************/
  404.  
  405. double getElement(gstr,gstart,gstop)
  406.  
  407. int  gstart, gstop;
  408. char *gstr;
  409.  
  410. {
  411.     double retval;
  412.     int    k, glength;
  413.     char   gestr[80];
  414.  
  415.     glength = gstop - gstart + 1;
  416.  
  417.     for (k = 0; k <= glength; k++)
  418.         gestr[k] = gstr[gstart+k-1];
  419.  
  420.     gestr[glength] = '\0';
  421.  
  422.     retval = (double) atof(gestr);
  423.     return(retval);
  424. }
  425.  
  426. /******************************************************************************/
  427. /*                                                                            */
  428. /* End of function block satelem.c                                            */
  429. /*                                                                            */
  430. /******************************************************************************/
  431.